UI
main.dart
import 'package:flutter/material.dart';
import 'Screen/home.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
Utils/colors
import 'package:flutter/material.dart';
Color primaryColor = const Color(0xffF5A624);
Color secondaryColor = const Color(0xffC7CFD7);
Color textColor = const Color(0xff415C77);
Screen/home
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:restaurant_booking_app/Model/mode.dart';
import 'package:restaurant_booking_app/Screen/restaurent_detail.dart';
import 'package:restaurant_booking_app/Utils/colors.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State createState() => _HomePageState();
}
class _HomePageState extends State {
int currentSelected = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
const Padding(
padding: EdgeInsets.only(
top: 55,
left: 25,
right: 25,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Discover",
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 55,
),
),
CircleAvatar(
backgroundImage: AssetImage("images/image1.png"),
),
],
),
),
const SizedBox(height: 20),
// for category selection
categorySelection(),
Expanded(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: restaurantItems.length,
itemBuilder: (context, index) {
final restaurant = restaurantItems[index];
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
RestaurentScreen(restaurant: restaurant),
),
);
},
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 25, vertical: 15),
child: Column(
children: [
Hero(
tag: restaurant.imageUrl,
child: Container(
height: 220,
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
image: DecorationImage(
image: NetworkImage(restaurant.imageUrl),
fit: BoxFit.fill),
),
),
),
Container(
padding: const EdgeInsets.all(20),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
),
boxShadow: [
BoxShadow(
blurRadius: 5,
spreadRadius: 5,
color: Colors.black12,
offset: Offset(0, 3),
),
]),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
restaurant.name,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
),
),
Text(
"${restaurant.totalReview} reviews = ${restaurant.level}",
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
color: Colors.black87,
),
)
],
),
CircleAvatar(
backgroundColor: primaryColor,
child: Text(
restaurant.rating,
style: const TextStyle(
color: Colors.white,
),
),
)
],
),
),
],
),
),
);
}),
),
],
),
);
}
Padding categorySelection() {
return Padding(
padding: const EdgeInsets.only(left: 25),
child: SizedBox(
height: 55,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categoryList.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
setState(() {
currentSelected = index;
});
},
child: Padding(
padding: const EdgeInsets.only(right: 5),
child: Column(
children: [
Container(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 13),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: currentSelected == index
? primaryColor
: secondaryColor,
),
child: Text(
categoryList[index],
style: const TextStyle(
fontSize: 18,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
],
),
),
);
}),
),
);
}
}
Screen/restaurent_detail
import 'package:flutter/material.dart';
import 'package:restaurant_booking_app/Model/mode.dart';
import 'package:restaurant_booking_app/Utils/colors.dart';
class RestaurentScreen extends StatelessWidget {
const RestaurentScreen({super.key, required this.restaurant});
final Restaurant restaurant;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
// for image
Hero(
tag: restaurant.imageUrl,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
restaurant.imageUrl,
),
fit: BoxFit.cover),
),
),
),
// for back or close button
Positioned(
top: 50,
right: 20,
child: CircleAvatar(
backgroundColor: Colors.white38,
child: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(
Icons.close,
size: 25,
color: Colors.white,
),
),
),
),
Positioned(
left: 30,
top: MediaQuery.of(context).size.height * 0.35,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.white38,
),
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 8,
),
child: const Text(
"Gromet",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.white,
),
),
),
// for name
Text(
restaurant.name,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 50,
color: Colors.white,
),
)
],
),
),
user(150, "images/image6.png", context),
user(125, "images/image5.png", context),
user(100, "images/image4.png", context),
user(75, "images/image3.png", context),
user(50, "images/image2.png", context),
Positioned(
top: MediaQuery.of(context).size.height * 0.48,
left: 30,
child: Container(
height: 46,
width: 46,
decoration: BoxDecoration(
color: primaryColor,
shape: BoxShape.circle,
border: Border.all(width: 1, color: Colors.white),
),
child: const Center(
child: Text(
"4.3",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
),
Positioned(
top: MediaQuery.of(context).size.height * 0.52,
left: 30,
child: Container(
margin: const EdgeInsets.only(top: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${restaurant.totalReview} reviews, 10 Friends",
style: const TextStyle(
fontSize: 18,
color: Colors.white,
fontWeight: FontWeight.bold),
)
],
),
),
),
Positioned(
bottom: 0,
child: Container(
padding: const EdgeInsets.only(left: 20, right: 20, top: 25),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.4,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
child: SingleChildScrollView(
child: Column(
children: [
for (Restaurant restaurant in restaurantItems)
Container(
padding: const EdgeInsets.only(bottom: 20),
child: Row(
children: [
Container(
height: 90,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
image: DecorationImage(
image: NetworkImage(restaurant.imageUrl),
fit: BoxFit.cover),
),
),
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
restaurant.description2,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
color: textColor,
),
),
const SizedBox(height: 10),
SizedBox(
width:
MediaQuery.of(context).size.width / 1.6,
child: Text(
restaurant.description1,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Colors.grey,
),
),
)
],
)
],
),
),
],
),
),
),
),
],
),
);
}
Positioned user(double leftPosition, String image, BuildContext context) {
return Positioned(
top: MediaQuery.of(context).size.height * 0.48,
left: leftPosition,
child: Container(
height: 46,
width: 46,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(image),
fit: BoxFit.cover,
),
shape: BoxShape.circle,
border: Border.all(width: 1, color: Colors.white),
),
),
);
}
}
Model/model
class Restaurant {
String name;
String imageUrl;
String rating;
String totalReview;
String level;
String description2;
String description1;
Restaurant({
required this.name,
required this.imageUrl,
required this.rating,
required this.totalReview,
required this.description2,
required this.description1,
required this.level,
});
}
List restaurantItems = [
Restaurant(
rating: '4.8',
name: "Joe's Linder",
imageUrl:
'https://images.cookforyourlife.org/wp-content/uploads/2019/10/healthy-diet-plate.jpg',
level: "S. Oxford 13th",
totalReview: "123",
description2: "Vegetables",
description1:
"At least halt of the grains vou eat should be whole grains. whole",
),
Restaurant(
rating: '4.5',
name: "Mama's brunch",
imageUrl: 'https://cdn.mos.cms.futurecdn.net/t4LzQQL75En7bRD7iyxNWd.jpg',
totalReview: "98",
level: "S. Gulier 6th",
description2: "Fruits",
description1:
"At least halt of the grains vou eat should be whole grains. whole",
),
Restaurant(
rating: '5.0',
name: "Dark table",
totalReview: "999",
imageUrl:
'https://i.pinimg.com/originals/1a/ce/34/1ace3490e2f113e4354a3001bf915dd9.jpg',
level: "S. Gulier 6th",
description2: "Juice",
description1:
"As the MyPlate icon shows, the five food groups are Fruits, Vegetables, ",
),
Restaurant(
rating: '4.2',
name: "Balanced Diet",
totalReview: "99",
imageUrl:
'https://www.alimentarium.org/sites/default/files/media/image/2017-04/EMAG_balanced_meal_shutterstock_54369673_TOP_0_0.jpg',
level: "S. Gulier 10th",
description2: "Balanced Diet",
description1:
" eating pattern with all five groups as key building blocks, plus oils.",
),
];
List categoryList = [
"healthy",
"italian",
"mexican",
"asian",
"chinese",
"haitian",
];